#ifndef __APP_DEVICE_H__
#define __APP_DEVICE_H__

#include "APP_Com.h"
#include "APP_Message.h"
#include "APP_Mqtt.h"
#include "APP_Pool.h"
#include "APP_Buffer.h"
#include "log.h"
#include "unistd.h"
#include <fcntl.h>
#include <stdlib.h>

typedef enum 
{
    Device_None, //当前网关设备未知
    Device_Serial,//当前网关设备 串口
    Device_Can//当前网关设备CAN
}DEVICE_TYPE;


typedef struct Device Device;

//本网关使用的是 蓝牙 与 下游传感器 单片机等硬件设备通信
//由于蓝牙透传模式的影响,网关只需要关注与蓝牙相连接串口的接收状况即可完成 与下游蓝牙设备或单片机的数据通信
struct Device
{
    //设备文件路径  网关设备的文件路径 本案例使用的是串口
    char* file_name;
    //文件描述符  网关 设备的文件描述符
    int fd;
    //设备类型  网关的设备类型
    DEVICE_TYPE Dev_type;
    //连接设备类型   匹配链接上的对端设备类型
    CONN_TYPE Conn_type;
    //读取缓冲区  (存放 从对端蓝牙设备读取信息)  对端蓝牙设备 -> 网关 -> 用户
    Buffer* read_buff;
    //写入缓冲区  (存放 接收到的上游用户发送信息)  用户 -> 网关 -> 对端蓝牙设备
    Buffer* write_buff;
    //读取到对端设备发送信息后的 数据格式处理函数指针   对端设备格式数据 -> 字节数组 存入读取缓冲区
    int(*post_read)(Device* device,char* data,int len);
    //网关数据发送到对端设备之前 数据格式处理函数指针   网关字节数组格式数据 -> 对端设备格式数据
    int(*pre_write)(Device* device,char* data,int len);
    //读取对端蓝牙数据的线程   该线程不断读取数据  当有数据时 就处理成网关格式数据 通过线程池线程发送到上游用户
    pthread_t read_thread;
    //网关设备的运行状态 0关闭 1运行中
    int running;
    //最后一次的写入时间 按照一定时间间隔向对端发送数据
    long long last_write_ts;//时间戳秒数
    //要求的最小时间间隔
    long write_interval_ms;//写入设备数据固定的最小间隔
};

//初始化 网关设备信息结构体
Device* APP_Device_Init(char* file_name);

//启动网关设备 阻塞读取对端设备信息的线程任务
int APP_Device_Start(Device* device);

//从对端设备读取信息线程的执行函数 内容:1.将读取到的对端设备数据格式转化为 字节数组 2.并写入读取缓冲区 3.最后提交缓冲区数据发送mqtt的任务
// 读取数据->改格式为字节数组->写入读缓冲区->提交mqtt发送任务给线程池
void*APP_Device_readfile(void* arg);

//往线程池中提交发送mqtt的任务
void* APP_Device_Mqtt_send(void* arg);

//有路由器接收数据  接收上游数据处理数据格式 -> 存入写缓冲区 -> 提交写入对端设备的线程池任务
int APP_Device_recv_router(Device* device,char* data,int len);

//将字节格式的数据 写入到对端设备中  处理数据格式->存入写缓冲区->提交线程池任务
void* APP_Device_Writefile(void* arg);

//释放设备资源
void APP_Device_free(Device *device);

#endif

